window: Add a delay before automatically showing mnemonics
authorRui Matos <tiagomatos@gmail.com>
Mon, 20 Aug 2012 23:28:25 +0000 (01:28 +0200)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 1 Sep 2012 02:53:23 +0000 (22:53 -0400)
Showing mnemonics immediately on modifier press can be annoying and
distracting when the user is just trying to Alt+Tab into another
application/window since the mnemonic will show up and quickly vanish
again when we receive the focus out event.

https://bugzilla.gnome.org/show_bug.cgi?id=672431

gtk/gtkmain.c
gtk/gtkwindow.c
gtk/gtkwindowprivate.h

index cce6416b6d27f22d87e687e565b3f43135285b82..56f2226d2f38eb2fdb84d8a1e2f3c93c492755c7 100644 (file)
@@ -1698,7 +1698,12 @@ gtk_main_do_event (GdkEvent *event)
 
               window = gtk_widget_get_toplevel (grab_widget);
               if (GTK_IS_WINDOW (window))
-                gtk_window_set_mnemonics_visible (GTK_WINDOW (window), mnemonics_visible);
+                {
+                  if (mnemonics_visible)
+                    _gtk_window_set_auto_mnemonics_visible (GTK_WINDOW (window));
+                  else
+                    gtk_window_set_mnemonics_visible (GTK_WINDOW (window), FALSE);
+                }
             }
         }
       /* else fall through */
index 2cffb13b854889acb0f30c0ee0f0e3dbeb097e49..05aea213f717c236b1446fcf80b5f3b29851c153 100644 (file)
@@ -98,6 +98,8 @@
  * </refsect2>
  */
 
+#define AUTO_MNEMONICS_DELAY 300 /* ms */
+
 typedef struct _GtkDeviceGrabInfo GtkDeviceGrabInfo;
 
 struct _GtkWindowPrivate
@@ -132,6 +134,8 @@ struct _GtkWindowPrivate
 
   guint16  configure_request_count;
 
+  guint    auto_mnemonics_timeout_id;
+
   /* The following flags are initially TRUE (before a window is mapped).
    * They cause us to compute a configure request that involves
    * default-only parameters. Once mapped, we set them to FALSE.
@@ -4783,6 +4787,12 @@ gtk_window_finalize (GObject *object)
 
   g_free (priv->startup_id);
 
+  if (priv->auto_mnemonics_timeout_id)
+    {
+      g_source_remove (priv->auto_mnemonics_timeout_id);
+      priv->auto_mnemonics_timeout_id = 0;
+    }
+
 #ifdef GDK_WINDOWING_X11
   g_signal_handlers_disconnect_by_func (gtk_settings_get_default (),
                                         gtk_window_on_theme_variant_changed,
@@ -9758,9 +9768,39 @@ gtk_window_set_mnemonics_visible (GtkWindow *window,
       g_object_notify (G_OBJECT (window), "mnemonics-visible");
     }
 
+  if (priv->auto_mnemonics_timeout_id)
+    {
+      g_source_remove (priv->auto_mnemonics_timeout_id);
+      priv->auto_mnemonics_timeout_id = 0;
+    }
+
   priv->mnemonics_visible_set = TRUE;
 }
 
+static gboolean
+set_auto_mnemonics_visible_cb (gpointer data)
+{
+  GtkWindow *window = data;
+
+  gtk_window_set_mnemonics_visible (window, TRUE);
+
+  window->priv->auto_mnemonics_timeout_id = 0;
+
+  return FALSE;
+}
+
+void
+_gtk_window_set_auto_mnemonics_visible (GtkWindow *window)
+{
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  if (window->priv->auto_mnemonics_timeout_id)
+    return;
+
+  window->priv->auto_mnemonics_timeout_id =
+    gdk_threads_add_timeout (AUTO_MNEMONICS_DELAY, set_auto_mnemonics_visible_cb, window);
+}
+
 /**
  * gtk_window_get_focus_visible:
  * @window: a #GtkWindow
index 51f7f95e85b066f2c13342c2f0da4c124ded6d57..22f8d57705a76d13e04105c8a935223279855417 100644 (file)
@@ -84,6 +84,8 @@ gboolean        _gtk_window_query_nonaccels     (GtkWindow      *window,
                                                  guint           accel_key,
                                                  GdkModifierType accel_mods);
 
+void            _gtk_window_set_auto_mnemonics_visible (GtkWindow *window);
+
 G_END_DECLS
 
 #endif /* __GTK_WINDOW_PRIVATE_H__ */